#include "BondDealMatrix.h"
#include "BondDealMatrixImpl.h"
#include "BondDealMatrixData.h"
#include "BondDealMatrixBlockBase.h"
#include "../StringResource.h"
#include <bondlib/BondContainer.h>
#include <bondlib/BondDeal/PanoramicBondDealStruct.h>
#include <core/FileSys.h>
#include <core/StyleMgr.h>
#include <core/ImageMgr.h>
#include <QGridLayout>
#include <QLabel>
#include <QSettings>

namespace {
	const int gap = 4;
	const int leftWidth = 48;
	const int topHeight = 24;
	const int blockWidth = 80;
	const int blockHeight = 52;
	
	const int maxColCount = 12;
	const int maxRowCount = 7;
}

BondDealMatrixImpl::BondDealMatrixImpl(QWidget* p)
	: QWidget(p)
	, m_showColCount(maxColCount - 1)
{
	m_layout = new QGridLayout;
	m_layout->setContentsMargins(0, 0, 0, 0);
	m_layout->setSpacing(gap);

	for (int col = 0; col < maxColCount; col++)
	{
		QLabel* head = new QLabel("", this);
		if(col == 0)head->setFixedSize(leftWidth, topHeight);
		head->setAlignment(Qt::AlignCenter);
		head->setIndent(gap);
		m_layout->addWidget(head, 0, col);
		if (col > 0)m_layout->setColumnMinimumWidth(col, blockWidth);
	}

	for (int row = 1; row < maxRowCount; row++)
	{
		QLabel* label = new QLabel("", this);
		label->setIndent(gap);
		m_layout->addWidget(label, row, 0);
		m_layout->setRowMinimumHeight(row, blockHeight);
	}	

	for (int row = 1; row < maxRowCount; row++)
	{
		for(int col = 1; col < maxColCount; col++)
		{
			BondDealMatrixBlockBase* block = new BondDealMatrixBlockBase(this);
			m_layout->addWidget(block, row, col);
		}
	}
	setLayout(m_layout);

	QString styleSheet = QString("QWidget {background-color:#%1}"
		"QLabel {background-color:#%2; color:#%3; margin:0; font:12px Microsoft YaHei;font-weight:bold}")
		.arg(StyleMgr::instance().color("BasicPlate").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("StaticTextBK").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16);
	setStyleSheet(styleSheet);

	setMouseTracking(true);
}

void BondDealMatrixImpl::setMatrixType(int type)
{
#define setLabelText(colname, rowname)\
{\
	for (auto col : m_vctColumn)\
	{\
		auto child = m_layout->itemAtPosition(0, col);\
		if(!child)continue;\
		QLabel* label = qobject_cast<QLabel*>(child->widget());\
		if (label)\
		{\
			label->setText(NewStringTable::colname(col));\
		}\
	}\
	for (auto row : m_vctRow)\
	{\
		auto child = m_layout->itemAtPosition(row, 0); \
		if (!child)continue;\
		QLabel* label = qobject_cast<QLabel*>(child->widget()); \
		if (label)\
		{\
			label->setText(NewStringTable::rowname(row)); \
		}\
	}\
}

	if (!m_layout)return;
	if (m_matrixType == type)return;
	m_matrixType = type;
	loadSetting();
	switch (m_matrixType)
	{
	case BondDealMatrix::eMTFixedIncomeGov:
		setLabelText(strBondDealGovHead, strBondDealGovType);
		break;
	case BondDealMatrix::eMTFixedIncomeCredit:
		setLabelText(strBondDealCreditHead, strBondDealCreditRate);
		break;
	case BondDealMatrix::eMTFixedIncomeNCDPrimary:
	case BondDealMatrix::eMTFixedIncomeNCD:
		setLabelText(strBondDealNCDHead, strBondDealNCDRate);
		break;
	default:
		break;
	}

	reloadData();
}

int BondDealMatrixImpl::getMatrixType()
{
	return m_matrixType;
}

void BondDealMatrixImpl::setMatrixData(BondDealMatrixData* pdata)
{
	m_pdata = pdata;
}

void BondDealMatrixImpl::getScrollRange(QRect& r, int& range, int& page) //返回滚动条range
{
	range = 0; page = 0;
	int w = r.width();
	m_showColCount = (w - leftWidth) / (blockWidth + gap);
	int colCount = m_vctColumn.size();
	if (colCount <= m_showColCount)
		return;

	range = colCount;
	page = m_showColCount;
}

void BondDealMatrixImpl::resize(int pos)
{
	int colCount = m_vctColumn.size();
	int i = 0;
	for (auto col : m_vctColumn)
	{
		if (i < pos || i >= m_showColCount + pos)
		{
			m_layout->setColumnMinimumWidth(col, 0);
			auto child = m_layout->itemAtPosition(0, col);
			if (child && child->widget())child->widget()->hide();

			for (auto row : m_vctRow)
			{
				child = m_layout->itemAtPosition(row, col);
				if (child && child->widget())
				{
					BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
					if (block)block->showCell(false);
				}
			}
		}
		else
		{
			m_layout->setColumnMinimumWidth(col, blockWidth);
			auto child = m_layout->itemAtPosition(0, col);
			if (child && child->widget())child->widget()->show();

			for (auto row : m_vctRow)
			{
				child = m_layout->itemAtPosition(row, col);
				if (child && child->widget())
				{
					BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
					if (block)block->showCell(true);
				}
			}
		}
		i++;
	}
}

void BondDealMatrixImpl::setDiffCDC(bool bDiffCDC)
{
	m_isDiffCDC = bDiffCDC;
}

void BondDealMatrixImpl::updateMatrix(int type)
{
#define setLabelText(colname, rowname)\
{\
	for (auto col : m_vctColumn)\
	{\
		auto child = m_layout->itemAtPosition(0, col);\
		if(!child)continue;\
		QLabel* label = qobject_cast<QLabel*>(child->widget());\
		if (label)\
		{\
			label->setText(NewStringTable::colname(col));\
		}\
	}\
	for (auto row : m_vctRow)\
	{\
		auto child = m_layout->itemAtPosition(row, 0); \
		if (!child)continue;\
		QLabel* label = qobject_cast<QLabel*>(child->widget()); \
		if (label)\
		{\
			label->setText(NewStringTable::rowname(row)); \
		}\
	}\
}
	if (!m_layout)return;
	if (m_matrixType != type)return;
	loadSetting();
	switch (m_matrixType)
	{
	case BondDealMatrix::eMTFixedIncomeGov:
		setLabelText(strBondDealGovHead, strBondDealGovType);
		break;
	case BondDealMatrix::eMTFixedIncomeCredit:
		setLabelText(strBondDealCreditHead, strBondDealCreditRate);
		break;
	case BondDealMatrix::eMTFixedIncomeNCDPrimary:
	case BondDealMatrix::eMTFixedIncomeNCD:
		setLabelText(strBondDealNCDHead, strBondDealNCDRate);
		break;
	default:
		break;
	}

	reloadData();
}

bool BondDealMatrixImpl::getTextShowType() const
{
	if (!m_pdata)	return false;
	return m_pdata->textShowType();
}

int BondDealMatrixImpl::getChartShowType() const
{
	if (!m_pdata)	return false;
	return m_pdata->chartShowType();
}

void BondDealMatrixImpl::loadSetting()
{
	m_vctColumn.clear();
	m_vctRow.clear();
	QSettings settings(FileSys::instance()->writeableAppCfgDir() + "/gszhConfig.ini", QSettings::IniFormat);
	switch (m_matrixType)
	{
	case BondDealMatrix::eMTFixedIncomeGov:
	{
		std::vector<UINT> vctRange;
		settings.beginGroup("fiGovRange");
		for (int i = BondDealMatrix::eGovTerm1Y; i < BondDealMatrix::eGovTermCount; i++)
		{
			QString name = QString("range%1").arg(i);
			switch (i)
			{
			case BondDealMatrix::eGovTerm15Y:
			case BondDealMatrix::eGovTerm20Y:
			case BondDealMatrix::eGovTerm30Y:
			case BondDealMatrix::eGovTerm50Y:
				vctRange.push_back(settings.value(name, 0).toInt());
				break;
			default:
				vctRange.push_back(settings.value(name, 1).toInt());
				break;
			}
		}
		settings.endGroup();
		int validCount = 0;
		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if (vctRange[i] == 1)
				validCount++;
		}
		if (validCount == 0)
		{
			for (int i = 0; i < BondDealMatrix::eGovTermCount - 1; i++)
				vctRange[i] = 1;
			vctRange[6] = 0;
			vctRange[7] = 0;
			vctRange[8] = 0;
			vctRange[9] = 0;
		}
		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if(vctRange[i] == 1)
				m_vctColumn.push_back(BondDealMatrix::eGovTerm1Y + i);
		}

		m_vctRow.push_back(BondDealMatrix::eTypeCountry);//国债
		m_vctRow.push_back(BondDealMatrix::eTypeCBDBond);//国开
		m_vctRow.push_back(BondDealMatrix::eTypeEximBank);//口行
		m_vctRow.push_back(BondDealMatrix::eTypeADBC);//农发
// 		m_vctRow.push_back(BondDealMatrix::eTypeOtherPolicy);//非国开
		m_vctRow.push_back(BondDealMatrix::eTypeMunicipal);//地方债)
		break;
	}
	case BondDealMatrix::eMTFixedIncomeCredit:
	{
		std::vector<UINT> vctRange;
		settings.beginGroup("fiGreditRange");
		for (int i = BondDealMatrix::eCreditTerm1M; i < BondDealMatrix::eCreditTermCount; i++)
		{
			QString name = QString("range%1").arg(i);
			switch (i)
			{
			case BondDealMatrix::eCreditTerm1M:
			case BondDealMatrix::eCreditTerm3M:
			case BondDealMatrix::eCreditTerm7Y:
			case BondDealMatrix::eCreditTerm10Y:
				vctRange.push_back(settings.value(name, 0).toInt());
				break;
			default:
				vctRange.push_back(settings.value(name, 1).toInt());
				break;

			}
		}
		settings.endGroup();
		int validCount = 0;
		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if (vctRange[i] == 1)
				validCount++;
		}
		if (validCount == 0)
		{
			for (int i = 0; i < BondDealMatrix::eCreditTermCount - 1; i++)
				vctRange[i] = 1;
			vctRange[0] = 0;
			vctRange[1] = 0;
			vctRange[8] = 0;
			vctRange[9] = 0;
		}

		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if (vctRange[i] == 1)
				m_vctColumn.push_back(BondDealMatrix::eCreditTerm1M + i);
		}

		m_vctRow.push_back(BondDealMatrix::eRateAAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAAA);
		m_vctRow.push_back(BondDealMatrix::eRateAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAA);
// 		m_vctRow.push_back(BondDealMatrix::eRateAAR);
		m_vctRow.push_back(BondDealMatrix::eRateOther);
		break;
	}
	case BondDealMatrix::eMTFixedIncomeNCDPrimary:
	{
// 		m_vctColumn.push_back(BondDealMatrix::eNCDTerm15D);
		m_vctColumn.push_back(BondDealMatrix::eNCDTerm1M);
// 		m_vctColumn.push_back(BondDealMatrix::eNCDTerm2M);
		m_vctColumn.push_back(BondDealMatrix::eNCDTerm3M);
		m_vctColumn.push_back(BondDealMatrix::eNCDTerm6M);
		m_vctColumn.push_back(BondDealMatrix::eNCDTerm9M);
		m_vctColumn.push_back(BondDealMatrix::eNCDTerm1Y);

		m_vctRow.push_back(BondDealMatrix::eRateAAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAAA);
		m_vctRow.push_back(BondDealMatrix::eRateAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAA);
		m_vctRow.push_back(BondDealMatrix::eRateAAR);
// 		m_vctRow.push_back(BondDealMatrix::eRateOther);
		break;
	}
	case BondDealMatrix::eMTFixedIncomeNCD:
	{
		std::vector<UINT> vctRange;
		settings.beginGroup("fiNCDRange");
		for (int i = BondDealMatrix::eNCDTerm15D; i < BondDealMatrix::eNCDTermCount; i++)
		{
			QString name = QString("range%1").arg(i);
			switch (i)
			{
			case BondDealMatrix::eNCDTerm15D:
				vctRange.push_back(settings.value(name, 0).toInt());
				break;
			default:
				vctRange.push_back(settings.value(name, 1).toInt());
				break;

			}
		}
		settings.endGroup();
		int validCount = 0;
		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if (vctRange[i] == 1)
				validCount++;
		}
		if (validCount == 0)
		{
			for (int i = 0; i < BondDealMatrix::eNCDTermCount - 1; i++)
			{
				vctRange[i] = 1;
			}
			vctRange[0] = 0;
		}

		for (int i = 0; i < (int)vctRange.size(); i++)
		{
			if (vctRange[i] == 1)
				m_vctColumn.push_back(BondDealMatrix::eNCDTerm15D + i);
		}

		m_vctRow.push_back(BondDealMatrix::eRateAAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAAA);
		m_vctRow.push_back(BondDealMatrix::eRateAAP);
		m_vctRow.push_back(BondDealMatrix::eRateAA);
// 		m_vctRow.push_back(BondDealMatrix::eRateAAR);
		m_vctRow.push_back(BondDealMatrix::eRateOther);
		break;
	}
	default:
		break;
	}

	for (int row = 1; row < maxRowCount; row++)
	{
		bool rowShow = (std::find(m_vctRow.begin(), m_vctRow.end(), row) != m_vctRow.end());
		if (rowShow)
		{
			m_layout->setRowMinimumHeight(row, blockHeight);
			auto child = m_layout->itemAtPosition(row, 0);
			if (child->widget())child->widget()->show();

			for (int col = 1; col < maxColCount; col++)
			{
				bool colShow = (std::find(m_vctColumn.begin(), m_vctColumn.end(), col) != m_vctColumn.end());
				if (colShow)
				{
					m_layout->setColumnMinimumWidth(col, blockWidth);
					auto child = m_layout->itemAtPosition(0, col);
					if (child && child->widget())child->widget()->show();

					child = m_layout->itemAtPosition(row, col);
					if (child && child->widget())
					{
						BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
						if (block)block->showCell(true);
					}
				}
				else
				{
					m_layout->setColumnMinimumWidth(col, 0);
					auto child = m_layout->itemAtPosition(0, col);
					if (child && child->widget())child->widget()->hide();

					child = m_layout->itemAtPosition(row, col);
					if (child && child->widget())
					{
						BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
						if (block)block->showCell(false);
					}
				}
			}
		}
		else
		{//整行隐藏
			m_layout->setRowMinimumHeight(row, 0);
			auto child = m_layout->itemAtPosition(row, 0);
			if (child && child->widget())child->widget()->hide();

			for (int col = 1; col < maxColCount; col++)
			{
				auto child = m_layout->itemAtPosition(row, col);
				if (child && child->widget())
				{
					BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
					if (block)block->showCell(false);
				}
			}
		}
	}
}

void BondDealMatrixImpl::reloadData()
{
	if (!m_pdata)return;
	for (int row = 1; row < maxRowCount; row++)
	{
		for (int col = 1; col < maxColCount; col++)
		{
			auto child = m_layout->itemAtPosition(row, col);
			if (!child || !child->widget())continue;
			BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
			if (!block)continue;

			int bondIndex = m_pdata->getCellData(m_matrixType, row, col);
			block->updateCell(bondIndex, false);
		}
	}
}

void BondDealMatrixImpl::updateCell(std::map<int, int>& mapCell)
{
	for (auto cell : mapCell)
	{
		if (m_pdata->getCellType(cell.first) != m_matrixType)continue;
		int row = m_pdata->getCellRow(cell.first);
		int col = m_pdata->getCellCol(cell.first);

		auto child = m_layout->itemAtPosition(row, col);
		if (!child || !child->widget())continue;
		BondDealMatrixBlockBase* block = dynamic_cast<BondDealMatrixBlockBase*>(child->widget());
		if (!block)continue;
		block->updateCell(cell.second, true);
	}
}

void BondDealMatrixImpl::leaveEvent(QEvent* event)
{
	qb::QBTips::hideTip();

	QWidget::leaveEvent(event);
}